/**
 * class name: tab,
 * copyright: maximus zhang,
 * License: MIT-LICENSE,
 * contact: maximus.zhang@gmail.com,
 * required-js: http://hcjs.googlecode.com/svn/trunk/hc.js,
 * update: http://hcjs.googlecode.com/svn/trunk/tab.js
 * -------
 * todo: remove tab; key; tab moving; tab pull out as popup; popup to tab
 */
function tab(){/* {tpid,cpid,onstyle,offstyle} */
    var A = arguments,
        _=this;
    _ = ext( _, ext( {
        id : 'tab'+ now(3),
        elem : me.body,
        css : '',
        ttl : 600,
        ico : {'close': '/icos/ishut.gif'},
        tabs : [
            {
                id:'newtab1',
                notab : false,
                rtl: false,
                tab : { label:'', cls:'', css:'' },
                ico : {src:'', css:'', alt:''},
                fn : function(){},
                key : '',
                data : '',
                locked : false,
                ttl : null
            }
        ] }, A[0]) );

    _.uitype = 'tab';

    _.elem = $(_.elem) || me.body;

    _.$ = {};/* store tab's data element */
    _.tab$ = {};/* store tabs json data */
    _.times = {};

    _.active = null;
    _.num = 0;

    _.timer = function(a){
        if ( !a || !a.nodeName=='A' ) {
            return false;
        }

        var id = attr(a,'href').replace(/^#/,'');

        if ( id=='' ) {
            return false;
        }

        if ( hop(_.times, id) ) {
            var ttl = typeof _.tab$[id].ttl=='number'
                ? _.tab$[id].ttl
                : _.ttl;

            if ( parseInt((now(2)-_.times[id])/1000, 10)>= ttl ) {
                delete _.times[id];
                return true;
            }
        }

    return false;
    };

    _.go = function(a){

        if ( typeof a=='string' ) {
            if ( !hop(_.tab$, a) ) {
                return false;
            }

            var a = $(_.tab$[a].id);
        } else if ( typeof a == 'object' && a ) {
            if ( !hop(_.tab$, a.id) ) {
                void _.add(a, _.tabroot);
            return _;
            }

            var a = $(a.id);
        }

        if ( a.nodeName && a.nodeName!='A' ) {
            a = geTags(a, 'A')[0];
        }

        _.click.apply(a);

    return _;
    };

    _.click = function(){/* to be call or apply only!! */
        if ( _.active && _.active.nodeName ) {
            if ( _.active==this ) {
                return true;
            }

            _.active.className = 'bz';
            _.times[attr(_.active,'href').replace(/^#/,'')] = now(2);
        }

        this.className = 'az';

        var id = attr(this,'href').replace(/^#/,'');

        if ( typeof _.tab$[id].data=='function' ) {
            if ( _.timer(this) ) {
                _.tab$[id].data(this);
            }
        }

        _.togg.apply(this, [id]);
        _.active = this;

    return _;
    };

    _.togg = function(a){/* to be call or apply only!! */
        if ( !a || a=='' || !_.$[a] ) {
            return null;
        }

        if ( _.active && _.active.nodeName ) {
            if ( _.active==this ) {
                return false;
            }
        }

        var pd = attr(_.active,'href').replace(/^#/,'');

        if ( _.$[pd] && _.$[pd].nodeName ) {
            _.$[pd].className='x';
        } else {
            for ( var v in _.$ ) {
                _.$[v].className = 'x';
            }
        }

        _.$[a].className = 'v';

    return true;
    };

    _.add = function(ot, el){
        if ( !ot || !el ) {
            return false;
        }

        if ( hop(_.$, ot.id) ) {
            return _.go(ot.id);
        }

        var li = elm('div').setClass('ly').appendTo(el);

        li.id = p(ot, 'id') && !$(ot.id) ? ot.id : '_tab_'+ now(2)*Math.random();
        if ( !p(ot, 'id') || ot.id!=li.id ) {
            ot.id = li.id;
        }

        if ( p(ot, 'css') ) {
            li.style.cssText = ot.css;
        }

        if ( ot.rtl ) {
            li.className = 'ry';
        }

        if ( !ot.notab ) {
            var a = elm('a').setClass('bz').appendTo(li);
            a.href = '#'+  li.id;
            if ( p(ot,'tab','cls') ) {
                a.className = ot.tab.cls;
                if ( ot.tab.cls=='az' ) {
                    if ( _.active && _.active.nodeName ) {
                        _.active.className = 'bz';

                        var pd = attr(_.active, 'href').replace(/^#/, '');

                        _.times[pd] = now(2);
                    }

                    if ( _.$[pd] && _.$[pd].nodeName ) {
                        _.$[pd].className = 'x';
                    } else {
                        for ( var v in _.$ ) {
                            _.$[v].className = 'x';
                        }
                    }
                    _.active = a;
                }
            }

            if ( p(ot, 'tab', 'css') ) {
                a.style.cssText = ot.tab.css;
            }

            a.onclick = function(ev){
                if ( _.click.apply(this, [ot.data]) ) {
                    return false;
                }

                if ( typeof ot.fn=='function' ) {
                    ot.fn.apply(this, [ot.data]);
                }

            return false;
            };

            if ( p(ot, 'ico', 'src') ) {
                var ico = elm('img').appendTo(a);
                ico.src = ot.ico.src;
                ico.className = 'ico';
                ico.alt = ot.ico.alt || '';
            }

            if ( p(ot.tab,'label') ) {
                var tx = elm('span').appendTo(a);
                tx.id = li.id +'_label';
                tx.className = 't';
                tx.innerHTML = ot.tab.label;
            }

            if ( p(ot,'key') ) {
                var em = elm('em').appendTo(a);
                em.innerHTML = '(<kbd>'+ ot.key +'<\/kbd>)';
            }

            var dv = elm('div').appendTo(_.tabdata),
                pz = pos(_.elem);

            dv.className = _.active==a ? 'v':'x';
            dv.id = li.id +'_tab';

            var div = elm('div').appendTo(dv);

            if ( typeof ot.data=='function' ) {
                var dat = ot.data.apply(div,[a]);
                if ( typeof dat=='string' ) {
                    div.innerHTML = dat;
                }
            } else if ( typeof ot.data=='string' ) {
                div.innerHTML = ot.data;
            } else if ( typeof ot.data=='object' && ot.data.nodeType ) {
                div.appendChild(ot.data);
            }

            /* tab close */
            if ( !ot.locked ) {
                var xx = elm('span').appendTo(a);

                xx.className = 'xx';
                xx.title = 'close tab';
                xx.style.cssText = 'background:url('+ _.ico.close +') 0 0 no-repeat;';

                xx.onmouseover = function(){
                    this.style.backgroundPosition = '-16px 0';
                };

                xx.onmouseout = function(){
                    this.style.backgroundPosition='0 0';
                };

                xx.onclick=function(){
                    if ( _.num<2 ) {
                        return false;
                    }

                    a.onclick = function(){return false;};

                    try {
                        delete _.$[li.id];
                        delete _.tab$[li.id];
                        _.tabroot.removeChild(li);
                        div.empty();
                        dv.empty();
                        _.tabdata.removeChild(dv);
                    } catch (ex) {
                    }

                    if ( _.active==a ) {
                        _.active = null;
                        for (var t in _.tab$) {
                            if ( _.active ) {
                                break;
                            }
                            if ( $(_.tab$[t].id).firstChild.nodeName=='A' ) {
                                $(_.tab$[t].id).firstChild.className = 'az';

                                if ( hop(_.$, _.tab$[t].id) ) {
                                    _.$[_.tab$[t].id].className = 'v';
                                }

                                _.active = $(_.tab$[t].id).firstChild;
                            }
                        }
                    }

                    _.num--;

                return false;
                };
            }

            _.num++;

        } else {
            li.className += ' xy';
            var dv = elm('div').appendTo(li);
            dv.id = ot.id +'_div';
            if ( typeof ot.data=='function' ) {
                var dat = ot.data.apply(dv,[dv]);
                if ( typeof dat=='string' ) {
                    dv.innerHTML = dat;
                }
            } else if ( typeof ot.data=='string' ) {
                dv.innerHTML = ot.data;
            } else if ( typeof ot.data=='object' && ot.data.nodeType ) {
                dv.appendChild(ot.data);
            }
        }


        _.tab$[li.id] = ot;
        _.$[li.id] = dv;


    return li;
    };

    _.init = function(){
        var pz = pos(_.elem);
        if ( _.elem.parentNode==me.body ) {
            _.elem.style.top = pz.top + (_.css.height ? _.css.height : 0) +'px';
            if ( $$.msie && $$.version<7 ) {
                me.documentElement.style.paddingTop = _.elem.style.top;
            }
        }
        _.root = elm('div').before(_.elem).setClass('tab');
        _.root.style.cssText = (_.css.height ? 'height:'+ _.css.height +'px;' : '') +'top:'+ (_.css.top ? _.css.top : pz.top) +'px';

        _.id = _.root.id = p(_,'id') && !$(_.id) ? _.id : ('tab'+ now(3));

        pz = pos(_.root);

        _.tabdata = elm('div').setClass('tab').appendTo(_.elem);

        var bar = elm('div').setClass('bx').appendTo(_.root);

        _.tabroot = elm('div').setClass('xl').appendTo(bar);

        for ( var z in _.tabs ) {
            void _.add(_.tabs[z], _.tabroot);
        }

        var ln = elm('div').appendTo(bar).setClass('line');

        if ( _.active==null && z ) {
            _.active = _.tabroot.firstChild.firstChild ? _.tabroot.firstChild.firstChild : _.tabroot.firstChild;
        }

    return _;
    };

}